package com.lzw.mall.common.service.impl;

import com.github.pagehelper.PageHelper;
import com.lzw.mall.common.entity.*;
import com.lzw.mall.common.mapper.*;
import com.lzw.mall.common.service.IOrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzw.mall.common.service.IPayService;
import com.lzw.mall.common.vo.LayuiTableVO;
import com.lzw.mall.common.vo.OrderSessionUtil;
import com.lzw.mall.common.vo.OrderVO;
import org.apache.activemq.ScheduledMessage;
import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.boot.autoconfigure.jms.JmsProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.jms.*;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lizhenwei
 * @since 2023-04-11
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {


    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

   @Autowired
   private OrderDetailsMapper orderDetailsMapper;

   @Autowired
   private MemberAddressMapper memberAddressMapper;

   @Autowired
   private OrderAddressMapper orderAddressMapper;

   @Autowired
   private OrdersMapper ordersMapper;

   @Autowired
   private IPayService payService;


    @Override
    @Transactional
    public Map<String, Object> saveOrder(String ids, Integer addId) {
        //1.获取当前用户
        Member m= OrderSessionUtil.getCurrent();

        BigDecimal sumPrice =new BigDecimal(0);
        for (String cartId: ids.split(",")){
            Cart cart=cartMapper.selectById(Integer.parseInt(cartId));
            Product p=productMapper.selectById(cart.getProductId());
            sumPrice=sumPrice.add(p.getPrice().multiply(new BigDecimal(cart.getAmount())));
        }

        //2.保存一个order对象
        Orders order=new Orders();
        order.setOrderDate(LocalDateTime.now());
        order.setMemberId(m.getId());
        order.setStatus("待支付");
        order.setTotalPrice(sumPrice);
        order.setPayType("alipay");

        //订单号不能重复
        //UUID
        //雪花算法  twitter  依赖当前时间
        //自定义流水号

        String pre="QGSC"+new SimpleDateFormat("yyMM").format(new Date());
        order.setOrderCode(getNextNo(pre));
        //保存订单主表位置
        baseMapper.insert(order);

        //订单详情表
        for (String cartId:ids.split(",")){
            OrderDetails orderDetail=new OrderDetails();
            Cart cart=cartMapper.selectById(Integer.parseInt(cartId));
            orderDetail.setOrderId(order.getId());
            orderDetail.setProductId(cart.getProductId());
            orderDetail.setAmount(String.valueOf(cart.getAmount()));
            Product p=productMapper.selectById(cart.getProductId());
            orderDetail.setProductName(p.getName());
            orderDetail.setPrice(p.getPrice());
            orderDetail.setProductImg(p.getHomeImg());
            orderDetailsMapper.insert(orderDetail);

            //删除购物车表
            cartMapper.deleteById(Integer.parseInt(cartId));
        }
        MemberAddress ma=memberAddressMapper.selectById(addId);
        //订单地址表
        OrderAddress oa=new OrderAddress();
        oa.setOrderId(order.getId());
        BeanUtils.copyProperties(ma, oa);//属性拷贝 注意导的包不一样，参数顺序不一样
        oa.setId(null);
        orderAddressMapper.insert(oa);

        //推送消息队列
        System.out.println(new Date()+"推送消息："+order.getId());
        delaySend(new ActiveMQQueue("order.save"),order.getId(),60000L);

        Map<String,Object> map = new HashMap<>();
        String qrCode=payService.createPayOrder(order);
        map.put("qrCode",qrCode);
        map.put("order",order);
        map.put("orderAddress",oa);

        //调用支付的session对接支付
        return map;
    }

    @Override
    public  List<OrderVO> selectOrderList(String status) {
        Member m=OrderSessionUtil.getCurrent();
        List<OrderVO> list =new ArrayList<>();
        List<Orders> orders=ordersMapper.selectOrderList(status,m.getId());
        for (Orders order: orders) {
            OrderVO vo = new OrderVO();
            vo.setOrderCode(order.getOrderCode());
            vo.setTotalPrice(order.getTotalPrice());
            vo.setOrderDate(order.getOrderDate());
            vo.setStatus(order.getStatus());
            vo.setList(orderDetailsMapper.selectListByOrderId(order.getId()));
            System.out.println("vo:"+vo);
            list.add(vo);
        }
        System.out.println(list);
        return list;
    }

    @Override
    public LayuiTableVO list(Integer page, Integer limit, String keyword, String status) {
        if (!status.equals("")){
            try {
                status=java.net.URLDecoder.decode(status, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
        PageHelper.startPage(page,limit);
        return LayuiTableVO.data(ordersMapper.selectListPage(keyword,status));
    }

    @Override
    public void updateStatus(Integer[] ids) {
        ordersMapper.updateStatus(ids);
    }

    @Override
    public void doUpdateStatus(String outTradeNo, String status) {
        ordersMapper.doUpdateStatus(outTradeNo,status);
    }

    //获取一个前缀
    private synchronized String getNextNo(String pre){
        Object obj=redisTemplate.opsForValue().get(pre);
        int nextNo;
        if (obj == null) {
            String maxCode =baseMapper.selectMaxCode(pre);
            if (maxCode==null) {
                nextNo=1;
            }else {
                String no=maxCode.substring(pre.length());
                nextNo=Integer.parseInt(no)+1;
            }
            redisTemplate.opsForValue().set(pre,nextNo);
        }else {
            nextNo=(int)obj;
            redisTemplate.opsForValue().set(pre,nextNo+1);
        }
        return pre+new DecimalFormat("0000").format(nextNo);
    }

    private <T extends Serializable> void delaySend(Destination queue, T data, Long time) {
        Connection conn = null;
        Session session = null;
        MessageProducer producer = null;
        ConnectionFactory connectionFactory = jmsMessagingTemplate.getConnectionFactory();
        try {
            conn = connectionFactory.createConnection();
            conn.start();
            session = conn.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
            //创建一个生产者
            producer = session.createProducer(queue);
            producer.setDeliveryMode(JmsProperties.DeliveryMode.PERSISTENT.getValue());
            ObjectMessage message = session.createObjectMessage(data);
            message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time);
            producer.send(message);
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (producer != null) {
                    producer.close();
                }
                if (session != null) {
                    session.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception ignored) {

            }
        }
    }

}